#include "settings.h"
#include "service.h"

#include <QSqlQuery>
#include <QSqlError>
#include <QDebug>

#include <QTextCodec>

QString Settings::iniPath()
{
    QString s = QCoreApplication::applicationDirPath()+"/"+QCoreApplication::applicationName();
    return s;
}


QSettings* Settings::getInstance()
{
    static QSettings s(Settings::iniPath()+".ini", QSettings::IniFormat);
    s.setIniCodec(QTextCodec::codecForName("UTF-8"));
    return &s;
}

void Settings::checkDefaults()
{
    QSettings *settings = Settings::getInstance();

    int size= settings->beginReadArray("operations");
    settings->endArray();
    if (size == 0){
        settings->beginWriteArray("operations");

        settings->setArrayIndex(0);
        settings->setValue("operation", "Вход");
        settings->setValue("module", "login");
        settings->setValue("params", "");

        settings->setArrayIndex(1);
        settings->setValue("operation", "Чек");
        settings->setValue("module", "cheque");
        settings->setValue("params", "");

        settings->setArrayIndex(2);
        settings->setValue("operation", "Возврат");
        settings->setValue("module", "cheque");
        settings->setValue("params", "cheque for return");

        settings->setArrayIndex(3);
        settings->setValue("operation", "Касса");
        settings->setValue("module", "moneymove");
        settings->setValue("params", "");

        settings->setArrayIndex(4);
        settings->setValue("operation", "Изм. цен");
        settings->setValue("module", "updatehistory");
        settings->setValue("params", "");

        settings->setArrayIndex(5);
        settings->setValue("operation", "Контакты");
        settings->setValue("module", "contacts");
        settings->setValue("params", "");

        settings->endArray();
    }
    settings->setValue("operations_defaults/operation_string",
                       settings->value("operations_defaults/operation_string", "operation:Чек|module:cheque|params:"));

    settings->setValue("globals/font_mono",
                       settings->value("globals/font_mono", "Deja Vu Sans Mono"));
    settings->setValue("globals/font_mono_size",
                       settings->value("globals/font_mono_size", 16));

    settings->setValue("globals/button_height",
                       settings->value("globals/button_height", 50));
    settings->setValue("globals/button_width",
                       settings->value("globals/button_width", 50));
    settings->setValue("globals/button_hmargin",
                       settings->value("globals/button_hmargin", 10));
    settings->setValue("globals/button_vmargin",
                       settings->value("globals/button_vmargin", 10));
    settings->setValue("globals/table_height",
                       settings->value("globals/table_height", 50));
    settings->setValue("globals/search_numcolumns",
                       settings->value("globals/search_numcolumns", 5));

    // global queries
    settings->setValue("queries/globals/get_essential",
                       settings->value("queries/globals/get_essential", "select VAL from IP$REKVISIT where NAME = :val"));
    settings->setValue("queries/globals/get_definition",
                       settings->value("queries/globals/get_definition", "select VALSQL from IP$OPREDEL where NAME = :def"));

    //login
    settings->setValue("queries/login/get_userslist",
                       settings->value("queries/globals/get_userslist","select name, id, pass from mst_sellers where pos_id = :pos order by name"));
    // cheque
    settings->setValue("queries/cheque/groupbuttons_are_visible",
                       settings->value("queries/cheque/groupbuttons_are_visible", 1));

    settings->setValue("queries/cheque/goodslist",
                       settings->value("queries/cheque/goodslist", "select g.id, b.barcode, g.articul, g.name, g.producer_name, g.price_sell from mst_goods g left join mst_goods_barcodes b on b.goods_id = g.id"));

    settings->setValue("queries/cheque/groupslist",
                       settings->value("queries/cheque/groupslist", "select id, name from mst_goodsgroups order by name"));
    settings->setValue("queries/cheque/search_by_barcode",
                       settings->value("queries/cheque/search_by_barcode", "select goods_id from mst_goods_barcodes where barcode = :val"));
    settings->setValue("queries/cheque/search_by_articul",
                       settings->value("queries/cheque/search_by_articul", "select id from mst_goods where articul = :val"));
    settings->setValue("queries/cheque/search_goods_by_id",
                       settings->value("queries/cheque/search_goods_by_id", "select articul, name, price_sell from mst_goods where id =  :val"));
    settings->setValue("queries/cheque/check_is_wgh_goods",
                       settings->value("queries/cheque/check_is_wgh_goods", "select is_wgh_goods from mst_goods where id = :val"));

    settings->setValue("queries/cheque/groupslist_with_params_preffics",
                       settings->value("queries/cheque/groupslist_with_params_preffics", "select id, articul, name, producer_name, price_sell from mst_goods"));
    settings->setValue("queries/cheque/groupslist_with_params_where",
                       settings->value("queries/cheque/groupslist_with_params_where", "where"));
    settings->setValue("queries/cheque/groupslist_with_params_suffics",
                       settings->value("queries/cheque/groupslist_with_params_suffics", "order by name"));

    settings->setValue("queries/cheque/get_new_document_id",
                       settings->value("queries/cheque/get_new_document_id", "select gen_id(GEN_MST_DOCUMENTS_ID,1) from rdb$database"));
    settings->setValue("queries/cheque/save_cheque",
                       settings->value("queries/cheque/save_cheque", "insert into mst_documents(id,ndoc,data,section_id,operation_id,analytic1_id,analytic3_id,summ) values (:id,:ndoc,:data,21,47,:store,:user,:summ)"));
    settings->setValue("queries/cheque/save_cheque_for_return",
                       settings->value("queries/cheque/save_cheque_for_return", "insert into mst_documents(id,ndoc,data,section_id,operation_id,analytic2_id,analytic3_id,summ) values (:id,:ndoc,:data,22,48,:store,:user,:summ)"));
    settings->setValue("queries/cheque/get_new_document_pos_id",
                       settings->value("queries/cheque/get_new_document_pos_id", "select gen_id(GEN_MST_DOCUMENTS_GOODS_ID,1) from rdb$database"));
    settings->setValue("queries/cheque/save_document_pos",
                       settings->value("queries/cheque/save_document_pos", "insert into mst_documents_goods(id,document_id,goods_id,kol,price,summ) values (:id,:document_id,:goods_id,:kol,:price,:summ)"));
    settings->setValue("queries/cheque/dpayers_list",
                       settings->value("queries/cheque/dpayers_list", "SELECT id, name, summ_ogr, (summ_ogr - coalesce((SELECT SUM(SUMM)FROM MST_RESTS rests WHERE rests.STATE_ID=10 AND rests.ANALYTIC_ID=dp.ID),0))  from mst_dpayers dp where BinAnd(dp.IP$FLAGS,4096) = 0 order by name"));


    settings->setValue("queries/moneymove/movslist",
                       settings->value("queries/moneymove/movslist", "select name, id from mst_operations where dview in ('внос денег','вынос денег') order by dview desc, id"));
    settings->setValue("queries/moneymove/first_pair_document",
                       settings->value("queries/moneymove/first_pair_document", "select first 1 data, cast(dtime as varchar(20)) from mst_documents where analytic1_id = :store and not analytic3_id = :user and section_id in (5,6,21,22) order by data desc, dtime desc"));
    settings->setValue("queries/moneymove/goods_operations_sum",
                       settings->value("queries/moneymove/goods_operations_sum", "select operation_name, sum(SUM_GOODS_SUM) from mst_documents where section_id in (21,22) and (data > :date_start or (data = :date_start2 and dtime > :time_start)) group by 1 "));
    settings->setValue("queries/moneymove/money_operations_sum",
                       settings->value("queries/moneymove/money_operations_sum", "select operation_name, sum(SUMM) from mst_documents where section_id in (5,6) and (data > :date_start or (data = :date_start2 and dtime > :time_start)) group by 1"));
    settings->setValue("queries/moneymove/rests_in_kassa_sum",
                       settings->value("queries/moneymove/rests_in_kassa_sum", "select summ from mst_rests where state_id = 10 and analytic_id = :store"));
    settings->setValue("queries/moneymove/get_section_id",
                       settings->value("queries/moneymove/get_section_id", "select id from mst_sections where dview = (select dview from mst_operations where id =  :operation_id)"));
    settings->setValue("queries/moneymove/get_new_document_id",
                       settings->value("queries/moneymove/get_new_document_id", "select gen_id(GEN_MST_DOCUMENTS_ID,1) from rdb$database"));
    settings->setValue("queries/moneymove/save_document",
                       settings->value("queries/moneymove/save_document", "insert into mst_documents(id,data,section_id,operation_id,summ,analytic1_id,analytic3_id) values (:id,:data,:section_id,:operation_id,:summ,:store,:user)"));

    settings->setValue("queries/pricehistory/get_history",
                       settings->value("queries/pricehistory/get_history", "select articul, name, (select first 1 data from mst_goods_pricehistory where goods_id = g.id order by data desc), (select first 1 price_sell from mst_goods_pricehistory where goods_id = g.id order by data desc) from mst_goods g order by 3 desc, 2 asc"));

    settings->setValue("queries/print/get_document",
                       settings->value("queries/print/get_document","select data, cast(dtime as varchar(20)), analytic1_id, analytic3_id, sum_goods_sum, summ, ndoc from mst_documents where id = :document_id"));
    settings->setValue("queries/print/get_document_pos",
                       settings->value("queries/print/get_document_pos","select goods_name, kol, price, summ from mst_documents_goods where document_id = :document_id"));


    settings->setValue("devices/comportscanner/is_enabled",
                       settings->value("devices/comportscanner/is_enabled", false));
    settings->setValue("devices/comportscanner/baudrate",
                       settings->value("devices/comportscanner/baudrate", 9600));
    settings->setValue("devices/comportscanner/databits",
                       settings->value("devices/comportscanner/databits", 7));
    settings->setValue("devices/comportscanner/device",
                       settings->value("devices/comportscanner/device", "/dev/ttyS0"));
    settings->setValue("devices/comportscanner/parity",
                       settings->value("devices/comportscanner/parity", 0));
    settings->setValue("devices/comportscanner/stopbits",
                       settings->value("devices/comportscanner/stopbits", 1));


    settings->setValue("devices/comportscales/is_enabled",
                       settings->value("devices/comportscales/is_enabled", false));
    settings->setValue("devices/comportscales/baudrate",
                       settings->value("devices/comportscales/baudrate", 9600));
    settings->setValue("devices/comportscales/databits",
                       settings->value("devices/comportscales/databits", 7));
    settings->setValue("devices/comportscales/device",
                       settings->value("devices/comportscales/device", "/dev/ttyS0"));
    settings->setValue("devices/comportscales/parity",
                       settings->value("devices/comportscales/parity", 0));
    settings->setValue("devices/comportscales/stopbits",
                       settings->value("devices/comportscales/stopbits", 1));


    settings->setValue("devices/printer/is_enabled",
                       settings->value("devices/printer/is_enabled", false));
    settings->setValue("devices/printer/name",
                       settings->value("devices/printer/name", "SITIZEN_CT-310II"));
}

QSettings* Settings::getUserInstance()
{
    static QSettings s(Settings::iniPath()+"_user.ini", QSettings::IniFormat);
    s.setIniCodec(QTextCodec::codecForName("UTF-8"));
    return &s;
}


QMap<QString,QVariant>* Settings::getVariables()
{
    static QMap<QString,QVariant> map;
    return &map;
}


Settings::Settings()
{
}


QString Settings::getEssential(const QString& ess)
{
    QSettings *settings =  Settings::getInstance();

    QSqlQuery query;
    query.prepare(settings->value("queries/globals/get_essential").toString());
    query.bindValue(":val", ess);

    if(!query.exec()){
        qDebug()<<posInFile<<query.lastError().text()<<endl<<query.lastQuery()<<endl<<query.boundValues();
        return QString("");
    }

    query.next();
    return query.value(0).toString();
}

QString Settings::getDefinition(const QString &def)
{
    QSettings *settings =  Settings::getInstance();

    QSqlQuery query;
    query.prepare(settings->value("queries/globals/get_definition").toString());
    query.bindValue(":def", def.toUtf8());

    //    QTextCodec::setCodecForLocale(QTextCodec::codecForName("Windows-1251"));
    if(!query.exec()){
        qDebug()<<posInFile<<query.lastError().text()<<endl<<query.lastQuery()<<endl<<query.boundValues();
        return QString("");
    }
    //qDebug()<<query.lastQuery()<<endl<<query.boundValues();

    query.next();
    return query.value(0).toString();
}

